#include "ui/panel.h"
#include "context.h"
#include "texture.h"
#include "shared.h"
#include "draw.h"
#include "font.h"
#include "ui/animation.h"

using namespace std;
using namespace anip;

ui::Panel::Panel(Container* parent, vec2 pos, vec2 size) :
	Scrollable(parent, pos, size)
{
	registerBindableRedraw(backColor);
	registerBindableRedraw(borderColor);
	registerBindableRedraw(borderWidth);
	registerBindableRedraw(roundRadius);
}

void ui::Panel::paint()
{
	Draw::roundedRect(_absPos, _size, roundRadius, backColor);
	Draw::roundedRectOutline(_absPos, _size, roundRadius, borderWidth, borderColor);
	Scrollable::paint();
	paintChildren();
	drawScrollers();
}

void ui::Panel::flow(Flow& f)
{
	if (layoutOptions.type != LayoutOptions::Flow)
		Control::flow(f);

	if (layoutOptions.stretchX > 0)
		_size.x = (f.borderRight - f.currentX) * layoutOptions.stretchX;
	
	if (layoutOptions.type == LayoutOptions::Flow)
	{
		flowChildrenDefault();
		// ANIP_FIXME: zero autosize?
		defaultFlowLayout(f);
	}
}

/////

ui::FoldablePanel::FoldablePanel(Container* parent, vec2 pos, vec2 size):
	WithText(parent, pos, size)
{
	registerBindableReflow(expandFactor);
	backColor = color{ 0.9f, 0.9f, 0.9f, 1 };
	roundRadius = 2;
}

int ui::FoldablePanel::getTextWidth()
{
	return (int)(_size.x - roundRadius * 0.6f - 15.0f);
}

void ui::FoldablePanel::processMouseButton(MouseButton btn, ButtonAction action)
{
	if (btn == MouseButton::Left && action == ButtonAction::Up
		&& toLocalPos(Context::mousePos()).y <= _headerSize.y)
	{
		// ANIP_TODO: this will be bad as long as ui::Animation isn't properly handled
		Animation::easeOutCubic(expandFactor, *this, expandFactor > 0.5f ? 0.0f : 1.0f, 0.5f);
		//expandFactor = expandFactor > 0.5f ? 0.0f : 1.0f;
	}

	WithText::processMouseButton(btn, action);
}

void ui::FoldablePanel::paint()
{
	auto textTex = getTextTexture();
	Draw::roundedRect(_absPos, _size, roundRadius, backColor);
	Draw::roundedRect(_absPos, _headerSize, roundRadius, headerColor);
	Draw::roundedRectOutline(_absPos, _size, roundRadius, borderWidth, borderColor);

	if (textTex != nullptr)
		Draw::text(_absPos + vec2{ roundRadius * 0.3f + 10.0f, 5.0f }, 
			textTex->size(), *textTex, textColor());

	// ANIP_TODO: draw a rotating triangle or sth

	Scrollable::paint();
	
	Context::addScissor(
		_absPos + vec2{ 0, _headerSize.y }, 
		_size - vec2{ 0, _headerSize.y });
	paintChildren();
}

void ui::FoldablePanel::flow(Flow& f)
{
	if (layoutOptions.type != LayoutOptions::Flow)
		Control::flow(f);

	if (layoutOptions.stretchX > 0)
		_size.x = (f.borderRight - f.currentX) * layoutOptions.stretchX;

	auto textTex = getTextTexture();
	vec2 tsize = textTex == nullptr ? vec2{ 0, 0 } : textTex->size();
	_headerSize = { _size.x, max((float)_font.size, tsize.y) + 10 + roundRadius };

	Flow ff(*this);
	//ff.containerHeight = HUGE_VALF;
	ff.currentY += _headerSize.y;
	flowChildren(ff);
	_contentHeight = ff.currentY - _headerSize.y;

	_size.y = expandFactor * _contentHeight + _headerSize.y;

	if (layoutOptions.type == LayoutOptions::Flow)
		defaultFlowLayout(f);

	postSignal({ ui::Signal::Type::NeedsRedraw });
}

void ui::FoldablePanel::setText(const wstring& text)
{
	WithText::setText(text);
	postSignal({ ui::Signal::Type::NeedsReflow });
}

void ui::FoldablePanel::setFont(const Font& font)
{
	WithText::setFont(font);
	postSignal({ ui::Signal::Type::NeedsReflow });
}